#include "dmcomm.h"
#include "hiddevice.h"
#include "serialdevice.h"
#include "virtualdevice.h"


std::atomic<bool> DmComm::s_initialized{false};

DmComm::DmComm()
{
    // 初始化前的断言检查（防止意外的重复初始化）
    assert(!s_initialized && "DmComm instance already created!");
    s_initialized = true;

    // 初始化逻辑（例如：加载资源、连接服务等）
    initialize();
}

DmComm::~DmComm()
{
    assert(s_initialized && "DmComm instance not created!");
    s_initialized = false;

    // 清理逻辑（例如：释放资源、断开连接等）
    cleanup();
}

void DmComm::initialize()
{
    // 实际初始化代码
}

void DmComm::cleanup()
{
    // 实际清理代码
}

DmComm &DmComm::getInstance()
{
    static DmComm instance;
    return instance;
}

bool DmComm::isInitialized()
{
    return s_initialized.load(std::memory_order_acquire);
}

void DmComm::registerErrorHandler(std::function<void (const int &)> handler)
{
    error = std::move(handler);
}

void DmComm::registerRecvHandler(std::function<void (const std::vector<uint8_t> &)> handler)
{
    recv = std::move(handler);
}

std::vector<DevInfo> DmComm::getDeviceInfo(bool contain) const
{
    std::vector<DevInfo> vect;
    if (contain) {
        vect.push_back({DevType::Virtual, "", "XXKJ", "DSP48"});
    }
    // HID
    const auto hids = HIDDevice::getDeviceInfo();
    vect.insert(vect.end(), hids.begin(), hids.end());
    // Serial
    // const auto serials = SerialDevice::getDeviceInfo();
    // vect.insert(vect.end(), serials.begin(), serials.end());
    return vect;
}

void DmComm::open(const DevInfo &info)
{
    std::lock_guard<std::mutex> lock(m_mutex);

    if (m_ptr && m_ptr->isOpen()) {
        m_ptr->close();
        m_ptr.reset();
    }

    switch (info.type) {
    case DevType::HID:
        m_ptr = std::make_unique<HIDDevice>(info.path);
        break;
    case DevType::Virtual:
        m_ptr = std::make_unique<VirtualDevice>(info.path);
        break;
    default:
        break;
    }

    if (m_ptr) {
        m_ptr->registerErrorHandler(error);
        m_ptr->registerRecvHandler(recv);
        m_ptr->open();
    }
}

bool DmComm::isOpen() const
{
    std::lock_guard<std::mutex> lock(m_mutex);
    return m_ptr && m_ptr->isOpen();
}

void DmComm::close()
{
    std::lock_guard<std::mutex> lock(m_mutex);
    if (!m_ptr || !m_ptr->isOpen()) {
        return;
    }

    m_closing = true;

    m_ptr->close();

    m_ptr.reset();

    m_closing = false;

}

void DmComm::write(const std::vector<uint8_t> &data, const uint16_t &timeout)
{
    std::lock_guard<std::mutex> lock(m_mutex);

    if (!m_ptr || m_closing || !m_ptr->isOpen()) {
        return;
    }

    m_ptr->write(data, timeout);
}


